package com.wangfugui.apprentice.controller;

import com.wangfugui.apprentice.common.util.BucketNameEnum;
import com.wangfugui.apprentice.common.util.MinIoClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;

@Api(tags = "文件操作接口")
@RestController
@RequestMapping(value = "/file")
public class FileController {

    @Autowired
    private MinIoClient client;

    @ApiOperation("上传一个文件")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseUtils upload(@RequestParam MultipartFile file, @RequestParam String bucket,
                                @RequestParam(required = false) String filePath) throws Exception {
        getclient().createBucket(bucket);
        String resp = getclient().upload(file.getInputStream(), file.getOriginalFilename(), filePath, BucketNameEnum.SAFETY);
        System.out.println(resp);
        return ResponseUtils.success();
    }

    @ApiOperation("下载一个文件")
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void download(@RequestParam String url, HttpServletResponse response) throws Exception {
        InputStream stream = client.downloadStream(url);
        ServletOutputStream output = response.getOutputStream();
        String objectName = "minio_" + System.currentTimeMillis();
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8"));
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        IOUtils.copy(stream, output);
    }

    private MinIoClient getclient() {
        return client;
    }

    @ApiOperation("列出所有的桶")
    @RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
    public ResponseUtils listBuckets() throws Exception {
        return ResponseUtils.success(getclient().listBuckets());
    }

    @ApiOperation("递归列出一个桶中的所有文件和目录")
    @RequestMapping(value = "/listFiles", method = RequestMethod.GET)
    public ResponseUtils listFiles(@RequestParam String bucket) {
        return ResponseUtils.success(getclient().listFiles(bucket));
    }

    @ApiOperation("删除一个文件")
    @RequestMapping(value = "/deleteFile", method = RequestMethod.GET)
    public ResponseUtils deleteFile(@RequestParam String bucket, @RequestParam String objectName) throws Exception {
        client.deleteObject(bucket, objectName);
        return ResponseUtils.success();
    }

    @ApiOperation("删除一个桶")
    @RequestMapping(value = "/deleteBucket", method = RequestMethod.GET)
    public ResponseUtils deleteBucket(@RequestParam String bucket) throws Exception {
        client.deleteBucket(bucket);
        return ResponseUtils.success();
    }


    @ApiOperation("复制一个文件")
    @GetMapping("/copyObject")
    public ResponseUtils copyObject(@RequestParam String sourceBucket, @RequestParam String sourceObject, @RequestParam String targetBucket, @RequestParam String targetObject) throws Exception {
        client.copyObject(sourceBucket, sourceObject, targetBucket, targetObject);
        return ResponseUtils.success();
    }

    @GetMapping("/getObjectInfo")
    @ApiOperation("获取文件信息")
    public ResponseUtils getObjectInfo(@RequestParam String bucket, @RequestParam String objectName) throws Exception {
        return ResponseUtils.success(client.getObjectInfo(bucket, objectName));
    }

    @GetMapping("/getPresignedObjectUrl")
    @ApiOperation("获取一个连接以供下载")
    public ResponseUtils getPresignedObjectUrl(@RequestParam String bucket, @RequestParam String objectName, @RequestParam Integer expires) throws Exception {
        return ResponseUtils.success(client.getPresignedObjectUrl(bucket, objectName, expires));
    }

    @GetMapping("/listAllFile")
    @ApiOperation("获取minio中所有的文件")
    public ResponseUtils listAllFile() throws Exception {

        return ResponseUtils.success(client.listAllFile());
    }

//    /**
//     * 处理大文件上传请求，将文件分片上传并合并。
//     *
//     * @param uploadFile 上传的文件，类型为MultipartFile，包含文件的原始数据。
//     * @param bucket     存储文件的桶名称，类型为String，指定文件存储的目标桶。
//     * @return 返回一个JSON格式的字符串，包含合并后的文件对象名称和存储桶名称。
//     * @throws RuntimeException 如果在上传或合并过程中发生异常，则抛出运行时异常。
//     */
//    @PostMapping("/uploadMp4LargeFile")
//    public String uploadLargeMp4File(@RequestParam MultipartFile uploadFile, @RequestParam String bucket) {
//        ObjectWriteResponse mergeResult;
//        try {
//            // 将上传的文件分片为多个输入流，便于后续分片上传
//            List<InputStream> inputStreams = client.splitFile(uploadFile);
//
//            // 获取上传分片的URL信息，包括原始文件名、分片数量和目标桶
//            String originalFilename = uploadFile.getOriginalFilename();
//            SplitFile splitFileDto = client.applyUploadPsiResult(originalFilename, inputStreams.size(), bucket);
//
//            // 将分片文件上传到MinIO服务器
//            client.uploadMp4(splitFileDto.getChunkUploadUrls(), inputStreams);
//
//            // 合并已上传的分片文件，完成整个文件的上传
//            mergeResult = client.mergeMultipartUpload(originalFilename, splitFileDto.getUploadId(), bucket);
//        } catch (Exception e) {
//            log.error("uploadLargeFile error", e);
//            throw new RuntimeException(e);
//        }
//
//        // 构造返回结果，包含合并后的文件对象名称和存储桶名称
//        JSONObject result = new JSONObject();
//        result.put("objectName", mergeResult.object());
//        result.put("bucketName", mergeResult.bucket());
//        return result.toJSONString();
//    }

}